/*
 * Copyright 2007 Jeffrey Palm
 */

import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;

public class TestSuite {
  
  public static void main(String[] args) {
    try {
      new TestSuite().realMain(args);
    } catch (Exception e) {e.printStackTrace();}
  }

  public void realMain(String[] args) throws Exception {
    //
    // Look up all the classes on the class path that are instances of
    // TestSupport and execute the main method
    //
    String classpath = System.getProperty("java.class.path");
    if (Util.isEmpty(classpath)) classpath = ".";
    List<Class> classes = new ArrayList<Class>();
    for (StringTokenizer st = new StringTokenizer(classpath,File.pathSeparator,false); st.hasMoreTokens();) {
      collect(st.nextToken().trim(),classes);
    }
    if (classes.isEmpty()) {
      note("no classes to run");
    } else {
      note("running classes:");
      for (Class c : classes) note(" - " + c);
    }
  }

  private void collect(String path, List<Class> res) throws Exception {
    File file = new File(path);
    note("looking at " + file);
    int len = file.getAbsolutePath().length() + 1;
    if (file.isDirectory()) {
      List<File> q = new ArrayList<File>();
      q.add(file);
      while (!q.isEmpty()) {
        File f = q.remove(0);
        if (f.isDirectory()) {
          File[] fs = f.listFiles();
          for (File ff : fs) q.add(ff);
        } else if (f.getName().endsWith(".class")) {
          maybeAdd(f.getAbsolutePath().substring(len),res);
        }
      }
    } else if (file.getName().endsWith(".jar")) {
      try {
        collect(new JarFile(file),res);
      } catch (Exception _) {}
    } else if (file.getName().endsWith(".zip")) {
      try {
        collect(new ZipFile(file),res);
      } catch (Exception _) {}
    } else {
      note("*** Don't know what to do with " + file + " ???");
    }
  }

  private void collect(ZipFile zf, List<Class> res) throws Exception {
    for (Enumeration en = zf.entries(); en.hasMoreElements();) {
      maybeAdd(((ZipEntry)en.nextElement()).getName(),res);
    }
  }

  private boolean maybeAdd(String className, List<Class> res) {
    className = className.replace(".class","").replace('/','.').replace('\\','.')
      .replace(File.separatorChar,'.');
    if (className.indexOf("$") != -1) return false;
    try {
      Class cls = Class.forName(className);
      for (Class trav=cls.getSuperclass(); trav != null && !trav.equals(Object.class); trav = trav.getSuperclass()) {
        if (trav.equals(TestSupport.class)) {
          res.add(cls);
          return true;
        }
      }
      return true;
    } catch (Throwable _) {return false;}
  }

  private void note(Object msg) {
    System.err.println(msg);
  }
}